| Anterior | Próximo | Índice |
A direferença entre uma rotina próxima e uma rotina distante é que nessa última o processador Intel salva o valor de CS e IP na pilha. Isso significa que para acessar um parâmetro devemos adicionar dois bytes a mais em BP já que há dois bytes extras na pilha (lembre-se: a pilha armazena palavras, que são dois bytes para o modo 8086 do processador, também chamado de Modo Real). Em modelos grandes de memória, uma rotina distante pode ser chamada de outro segmento diferente do da rotina chamadora. A rotina distante deve terminar com um RETF (far return) para atualizar CS:IP com o endereço de retorno. O deslocamento de cada parâmetro na pilha, em relação ao endereço base , que é dado por SS, devem ser esses:
SP = Valor Inicial de SP SP - 02 = Valor de SP após empilhar o primeiro parâmetro SP - 04 = Valor de SP após empilhar o segundo parâmetro SP - 06 = Valor de SP após empilhar o terceiro parâmetro SP - 08 = Valor de SP após a chamada da rotina empilhar o valor de CS SP - 10 = Valor de SP após a rotina empilhar o valor IP SP - 12 = Valor de SP após empilhar o valor de BPPara acessar cada parâmetro você deve considerar a seguinte aritmética:
Endereço do primeiro parâmetro em relação a SS = [BP + 10] = [(SP - 12) + 10] = [SP - 2]
Endereço do segundo parâmetro em relação a SS= [BP + 08] = [(SP - 12) + 08] = [SP - 4]
Endereço do terceiro parâmetro em relação a SS = [BP + 06] = [(SP - 12) + 06] = [SP - 6]
E como você pode constantar acima, o resultado confere com os deslocamentos esperados para cada parâmetro na pilha.
;PROCF.ASM
;DEMONSTRACAO DE UMA ROTINA COM 3 PARAMETROS
;CHAMAR DE PROGRAMA EM TURBO PASCAL
;PARA MONTAR DIGITE: nasm -fobj procf.asm
segment CODE class=CODE align=1
;------------------------------------------------------
;function ParamDemo(x, y, z : integer):integer;external
;------------------------------------------------------
GLOBAL ParamDemo
ParamDemo:
PUSH BP
MOV BP,SP
PUSH DS
MOV AX, [BP + 10] ; AX := primeiro parametro
ADD AX, [BP + 08] ; soma AX com segundo parametro
ADD AX, [BP + 06] ; soma AX com terceiro parametro
POP DS
POP BP
RETF 2+2+2 ; retira os 3 parametros da pilha
{ Essa é a rotina em Turbo Pascal que chama a rotina assembly }
{$F+} { Força chamada distante }
program ParametroDemo;
{$L PROCF}
function ParamDemo(x,y,z: integer): integer; external;
var total: integer;
BEGIN
total := ParamDemo(1,2,3);
writeln;
writeln('1+2+3 = ',total);
END.
|
| Anterior | Próximo | Índice |